# HUB 插件 - 简化版进度显示模块
# 实现状态栏的纯文本进度显示功能

require 'sketchup.rb'

module HUB
  module JDT
    # 使用file_loaded?机制防止重复加载
    unless file_loaded?(__FILE__)
      # 进度显示状态 - 使用嵌套哈希，外层键为模型ID，内层键为进度ID
      @active_progress = {}
      
      # 当前活动的进度ID - 使用哈希，键为模型ID
      @current_progress_id = {}
      
      # 上次更新时间 - 使用嵌套哈希，外层键为模型ID，内层键为进度ID
      @last_update_time = {}
      
      # 定时器ID，用于跟踪和停止定时器 - 使用哈希，键为模型ID
      @timer_id = {}
      
      # 进度ID到模型ID的映射，用于在窗口切换时找到正确的模型ID
      @progress_model_map = {}
      
      # 日志记录函数
      def self.log(message, level = 2)
        prefix = case level
          when 1 then "[DEBUG]"
          when 2 then "[INFO]"
          when 3 then "[ERROR]"
          else "[LOG]"
        end
        
        puts "#{prefix} #{Time.now.strftime('%Y-%m-%d %H:%M:%S')} - JDT: #{message}"
      end
      
      # 标记此文件已加载
      file_loaded(__FILE__)
      
      # 不再在模块加载时启动定时器，而是在需要时启动
    end
    
    # 获取当前活动模型的唯一ID
    # @return [String] 模型的唯一标识符
    def self.get_model_id
      model = Sketchup.active_model
      # 使用model.object_id作为唯一标识符
      model_id = model.object_id.to_s
      log("当前模型ID: #{model_id}", 1)
      return model_id
    end
    
    # 获取进度对应的模型ID
    # @param progress_id [String] 进度ID
    # @return [String] 对应的模型ID，如果找不到则返回当前活动模型的ID
    def self.get_model_id_for_progress(progress_id)
      # 如果映射表中有这个进度ID的记录，则返回对应的模型ID
      if @progress_model_map[progress_id]
        model_id = @progress_model_map[progress_id]
        log("从映射找到进度 #{progress_id} 对应的模型ID: #{model_id}", 1)
        return model_id
      end
      
      # 如果找不到映射，则遍历所有模型查找该进度ID
      @active_progress.each do |model_id, progress_map|
        if progress_map[progress_id]
          # 找到了进度ID，更新映射表并返回
          @progress_model_map[progress_id] = model_id
          log("通过搜索找到进度 #{progress_id} 对应的模型ID: #{model_id}", 1)
          return model_id
        end
      end
      
      # 如果都找不到，返回当前活动模型ID
      model_id = get_model_id
      log("无法找到进度 #{progress_id} 对应的模型ID，使用当前模型: #{model_id}", 1)
      return model_id
    end
    
    # 启动清理定时器
    def self.start_cleanup_timer
      model_id = get_model_id
      
      # 如果该模型的定时器已经在运行，不要重复启动
      return if @timer_id[model_id]
      
      begin
        @timer_id[model_id] = UI.start_timer(10, true) { cleanup_progress(model_id) }
        log("已启动进度清理定时器，模型ID: #{model_id}")
      rescue => e
        log("启动定时器失败: #{e.message}", 3)
      end
    end
    
    # 停止清理定时器
    # @param model_id [String] 模型ID，如果为nil则使用当前活动模型
    def self.stop_cleanup_timer(model_id = nil)
      model_id ||= get_model_id
      
      # 只有在定时器存在时才尝试停止
      return unless @timer_id[model_id]
      
      begin
        UI.stop_timer(@timer_id[model_id])
        @timer_id.delete(model_id)
        log("已停止进度清理定时器，模型ID: #{model_id}")
      rescue => e
        log("停止定时器失败: #{e.message}", 3)
      end
    end
    
    # 生成唯一的进度ID
    def self.generate_unique_id
      "progress_#{Time.now.to_i}_#{rand(10000)}"
    end
    
    # 创建上传进度
    # @param title [String] 标题
    # @param filename [String] 文件名（可选）
    # @return [String] 进度ID
    def self.create_upload_progress(title = "上传", filename = nil)
      model_id = get_model_id
      progress_id = generate_unique_id
      
      # 确保定时器已启动
      start_cleanup_timer
      
      # 确保模型的状态存储结构初始化
      @active_progress[model_id] ||= {}
      @last_update_time[model_id] ||= {}
      
      # 存储进度信息
      @active_progress[model_id][progress_id] = {
        id: progress_id,
        title: title,
        filename: filename,
        progress: 0,
        created_at: Time.now,
        last_update: Time.now,
        completed: false,
        type: :upload
      }
      
      # 记录进度ID到模型ID的映射
      @progress_model_map[progress_id] = model_id
      
      # 设置当前活动进度ID
      @current_progress_id[model_id] = progress_id
      
      # 显示初始进度
      display_progress(progress_id, 0, "正在准备...")
      
      log("创建上传进度: #{title}, ID: #{progress_id}, 模型ID: #{model_id}")
      
      return progress_id
    end
    
    # 创建下载进度
    # @param title [String] 标题
    # @param filename [String] 文件名（可选）
    # @return [String] 进度ID
    def self.create_download_progress(title = "下载", filename = nil)
      model_id = get_model_id
      progress_id = generate_unique_id
      
      # 确保定时器已启动
      start_cleanup_timer
      
      # 确保模型的状态存储结构初始化
      @active_progress[model_id] ||= {}
      @last_update_time[model_id] ||= {}
      
      # 存储进度信息
      @active_progress[model_id][progress_id] = {
        id: progress_id,
        title: title,
        filename: filename,
        progress: 0,
        created_at: Time.now,
        last_update: Time.now,
        completed: false,
        type: :download
      }
      
      # 记录进度ID到模型ID的映射
      @progress_model_map[progress_id] = model_id
      
      # 设置当前活动进度ID
      @current_progress_id[model_id] = progress_id
      
      # 显示初始进度
      display_progress(progress_id, 0, "正在准备...")
      
      log("创建下载进度: #{title}, ID: #{progress_id}, 模型ID: #{model_id}")
      
      return progress_id
    end
    
    # 更新进度
    # @param progress_id [String] 进度ID
    # @param percent [Integer] 完成百分比 (0-100)
    # @param message [String] 状态消息（可选）
    def self.update_progress(progress_id, percent, message = nil)
      # 使用进度ID找到对应的模型ID
      model_id = get_model_id_for_progress(progress_id)
      
      # 检查该模型是否有此进度ID
      return unless @active_progress[model_id] && @active_progress[model_id][progress_id]
      
      # 限制更新频率，避免频繁刷新
      now = Time.now
      @last_update_time[model_id] ||= {}
      last_time = @last_update_time[model_id][progress_id] || (now - 1)
      if now - last_time < 0.1 && percent < 100 && percent > 0
        return
      end
      @last_update_time[model_id][progress_id] = now
      
      begin
        # 限制百分比在0-100之间
        percent = [0, [percent, 100].min].max
        
        # 更新进度信息
        @active_progress[model_id][progress_id][:progress] = percent
        @active_progress[model_id][progress_id][:last_update] = now
        if message
          @active_progress[model_id][progress_id][:message] = message
        end
        
        # 显示进度
        display_progress(progress_id, percent, message)
        
        log("更新进度: #{percent}% (ID: #{progress_id}, 模型ID: #{model_id})")
      rescue => e
        log("更新进度时出错: #{e.message}", 3)
      end
    end
    
    # 标记进度完成
    # @param progress_id [String] 进度ID
    # @param message [String] 完成消息（可选）
    def self.complete_progress(progress_id, message = "已完成")
      # 使用进度ID找到对应的模型ID
      model_id = get_model_id_for_progress(progress_id)
      
      # 检查该模型是否有此进度ID
      return unless @active_progress[model_id] && @active_progress[model_id][progress_id]
      
      begin
        # 更新完成状态
        @active_progress[model_id][progress_id][:progress] = 100
        @active_progress[model_id][progress_id][:completed] = true
        @active_progress[model_id][progress_id][:last_update] = Time.now
        if message
          @active_progress[model_id][progress_id][:message] = message
        end
        
        # 获取操作类型
        type = @active_progress[model_id][progress_id][:type]
        title = type == :upload ? "上传" : "下载"
        
        # 显示100%进度
        display_progress(progress_id, 100, message)
        
        log("#{title}进度已完成 (ID: #{progress_id}, 模型ID: #{model_id})")
        
        # 安排清理（2秒后隐藏）
        UI.start_timer(2) {
          hide_progress(progress_id)
        }
      rescue => e
        log("标记进度完成时出错: #{e.message}", 3)
      end
    end
    
    # 显示进度信息
    # @param progress_id [String] 进度ID
    # @param percent [Integer] 完成百分比
    # @param message [String] 状态消息（可选）
    def self.display_progress(progress_id, percent, message = nil)
      # 使用进度ID找到对应的模型ID
      model_id = get_model_id_for_progress(progress_id)
      
      # 检查该模型是否有此进度ID
      return unless @active_progress[model_id] && @active_progress[model_id][progress_id]
      
      begin
        # 获取进度信息
        progress_info = @active_progress[model_id][progress_id]
        type = progress_info[:type]
        title = progress_info[:title] || (type == :upload ? "上传" : "下载")
        
        # 构建显示文本
        if percent > 0
          display_text = "#{title}中：#{percent}%"
        else
          display_text = "#{title}：准备中..."
        end
        
        # 添加消息（如果有）
        if message && !message.empty?
          display_text += " - #{message}"
        end
        
        # 设置状态栏文本
        Sketchup.status_text = display_text
        log("更新状态栏: #{display_text}", 1)
      rescue => e
        log("显示进度时出错: #{e.message}", 3)
      end
    end
    
    # 隐藏进度显示
    # @param progress_id [String] 进度ID
    def self.hide_progress(progress_id)
      # 使用进度ID找到对应的模型ID
      model_id = get_model_id_for_progress(progress_id)
      
      # 检查是否有效的进度ID
      return unless progress_id && @active_progress[model_id] && @active_progress[model_id][progress_id]
      
      begin
        # 只有当要隐藏的进度是当前活动的进度时，才清除状态栏
        if @current_progress_id[model_id] == progress_id
          Sketchup.status_text = ""
          @current_progress_id.delete(model_id)
        end
        
        # 清理资源
        @active_progress[model_id].delete(progress_id)
        @last_update_time[model_id].delete(progress_id) if @last_update_time[model_id]
        
        # 清理进度ID到模型ID的映射
        @progress_model_map.delete(progress_id)
        
        log("隐藏并清理进度 (ID: #{progress_id}, 模型ID: #{model_id})")
        
        # 如果该模型没有活动的进度显示了，停止定时器
        if @active_progress[model_id].empty?
          stop_cleanup_timer(model_id)
          # 如果该模型的进度数据为空，清理相关数据结构
          @active_progress.delete(model_id)
          @last_update_time.delete(model_id)
        end
      rescue => e
        log("隐藏进度显示时出错: #{e.message}", 3)
      end
    end
    
    # 清理过期的进度显示
    # @param model_id [String] 模型ID，如果为nil则使用当前活动模型
    def self.cleanup_progress(model_id = nil)
      model_id ||= get_model_id
      
      # 如果该模型没有进度记录，直接返回
      return unless @active_progress[model_id]
      
      begin
        now = Time.now
        to_remove = []
        
        @active_progress[model_id].each do |id, info|
          # 如果已完成且最后更新时间超过5秒，或创建时间超过5分钟，则标记为删除
          if (info[:completed] && (now - info[:last_update] > 5)) || 
             (now - info[:created_at] > 300)
            to_remove << id
          end
        end
        
        # 移除过期进度
        to_remove.each do |id|
          hide_progress(id)
        end
        
        if to_remove.size > 0
          log("自动清理了 #{to_remove.size} 个过期进度显示，模型ID: #{model_id}")
        end
        
        # 如果该模型的清理后没有活动进度了，停止定时器
        if !@active_progress[model_id] || @active_progress[model_id].empty?
          stop_cleanup_timer(model_id)
          # 清理相关数据结构
          @active_progress.delete(model_id)
          @last_update_time.delete(model_id)
        end
      rescue => e
        log("清理过期进度显示时出错: #{e.message}", 3)
      end
    end
    
  end # module JDT
end # module HUB
